package com.shanghaionstar.vehicle_ownerlife;

import android.content.Context;
import android.graphics.PixelFormat;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;

import com.shanghaionstar.R;

/**
 * 浮动窗口辅助类：
 *    显示全局或页面浮动页面
 * 使用方式：
 *    FloatWindowUtil util = new FloatWindowUtil(this).createWindow();
 *
 * Created by Yonglang Hong on 2017/1/9.
 */
public class FloatWindowUtil {

    String TAG = FloatWindowUtil.class.getSimpleName();

    WindowManager mWindowManager;
    WindowManager.LayoutParams wmParams;
    LinearLayout mFloatLayout;
    Button mFloatView;

    /**
     * 最小移动距离，downX,downY,moveX,moveY,移动距离
     */
    int touchSlop, dX, dY, mX, mY, dst;

    /**
     * 边距
     */
    final static int margin = 20;

    Context context;

    /**
     * floatview点击事件
     */
    View.OnClickListener onClickListener;

    public void setOnClickListener(View.OnClickListener onClickListener) {
        this.onClickListener = onClickListener;
    }

    /**
     * context若是activity获取的WindowManager则是LocalWindowManager,此时浮动窗口只在当前activity页面显示
     * 若需要全局窗口则用application的context句柄,此时获取的是WindowManagerImpl实例
     */
    public FloatWindowUtil(Context context) {
        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        this.context = context;
    }

    /**
     * 创建浮动窗口
     */
    public void createWindow() {
        setUpWindowParam();
        addViewToWindow();
    }

    /**
     * 设置WindowManager参数
     */
    private void setUpWindowParam() {
        wmParams = new WindowManager.LayoutParams();
        //获取的是WindowManagerImpl.CompatModeWrapper
        Log.i(TAG, "mWindowManager--->" + mWindowManager);
        //设置window type
        wmParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
        //设置图片格式，效果为背景透明
        wmParams.format = PixelFormat.RGBA_8888;
        //设置浮动窗口不可聚焦（实现操作除浮动窗口外的其他可见窗口的操作）
        wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        //调整悬浮窗显示的停靠位置为左侧置顶
        wmParams.gravity = Gravity.LEFT | Gravity.TOP;
        // 以屏幕左上角为原点，设置x、y初始值，相对于gravity
        wmParams.x = margin;
        wmParams.y = margin;
        //设置悬浮窗口长宽数据
        wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
    }

    /**
     * 将view添加到window
     */
    private void addViewToWindow() {
        //获取浮动窗口视图所在布局
        mFloatLayout = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.floatview, null);
        mFloatView = (Button) mFloatLayout.findViewById(R.id.btn);
        //浮动窗口按钮
//        mFloatLayout.measure(View.MeasureSpec.makeMeasureSpec(0,
//                View.MeasureSpec.UNSPECIFIED), View.MeasureSpec
//                .makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
//        Log.i(TAG, "Width/2--->" + mFloatView.getMeasuredWidth() / 2);
//        Log.i(TAG, "Height/2--->" + mFloatView.getMeasuredHeight() / 2);
        //设置触摸移动事件
        setTouchListener();
        //设置点击事件
        setClickListener();
        //添加mFloatLayout
        mWindowManager.addView(mFloatLayout, wmParams);
    }

    private void setTouchListener() {
        //最小移动范围
        touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        //设置监听浮动窗口的触摸移动
        mFloatView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                //getRawX是触摸位置相对于屏幕的坐标，getX是相对于按钮的坐标
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        dX = (int) event.getRawX();
                        dY = (int) event.getRawY();
                        dst = 0;
                        break;
                    case MotionEvent.ACTION_UP:
                        if (dst >= touchSlop) {
                            //屏幕左右停靠
                            wmParams.x = mX <= getScreenWidth() / 2 ? margin : getScreenWidth() - mFloatView.getMeasuredWidth() - margin;
                            if (wmParams.y < margin)
                                wmParams.y = margin;
                            if (wmParams.y > getScreenHeight() - mFloatView.getMeasuredHeight() - margin)
                                wmParams.y = getScreenHeight() - mFloatView.getMeasuredHeight() - margin;
                            mWindowManager.updateViewLayout(mFloatLayout, wmParams);
                            return true;
                        }
                    case MotionEvent.ACTION_MOVE:
                        mX = (int) event.getRawX();
                        mY = (int) event.getRawY();
                        dst = (int) Math.sqrt(Math.pow(mY - dY, 2) + Math.pow(mX - dX, 2));
                        if (dst >= touchSlop) {
                            wmParams.x = (int) event.getRawX() - mFloatView.getMeasuredWidth() / 2;
                            wmParams.y = (int) event.getRawY() - mFloatView.getMeasuredHeight() / 2;
                            mWindowManager.updateViewLayout(mFloatLayout, wmParams);
                            return true;
                        }
                        break;
                }
                return false;
            }
        });
    }

    private void setClickListener() {
        mFloatView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mWindowManager.removeView(mFloatLayout);
                if (onClickListener != null)
                    onClickListener.onClick(v);
            }
        });
    }

    private int getScreenWidth() {
        DisplayMetrics metrics = new DisplayMetrics();
        mWindowManager.getDefaultDisplay().getMetrics(metrics);
        return metrics.widthPixels;
    }

    private int getScreenHeight() {
        DisplayMetrics metrics = new DisplayMetrics();
        mWindowManager.getDefaultDisplay().getMetrics(metrics);
        return metrics.heightPixels;
    }

}
